# coding=UTF-8
from PySFML import sf
import anim
import cmath
import boule

class Personnage(boule.Boule):
        vel_moving = 2
	"""
    jump = False
    img = sf.Image()
    force_img = sf.Image()
    barre_energie = sf.Image()
    barre_energie_vide = sf.Image()

    velx = 20
    vely = 20
    vel_moving = 8
    vel_grav = 0.2
    sol = 100
    vel_jumping = 10
    screen_width = 800
    screen_height = 600
    impact = 0
    force = -1
    energie = 0
    niveau_gauge_energie = 0
    p=complex()

    keys = []
    time_update = 0
    time = 0
    feu = False

    immobilisation = 0
    moteur_p = 0
    velx_prec = 0
        """
	def __init__(self, w, p0, bar_x, bar_y, position, name, moteur_p, carte):
    	
 		boule.Boule.__init__(self, 500, 25, p0, complex(0, 30), complex(0, 0.15), 0.5, 0.03, "personnage")
#        self.p = complex(150,400) # position initiale
#        self.v = complex(0, 0)
#        self.r = 25
#        self.m = 500
#        self.bounce_friction = 0.1
        	self.carte = carte
#        self.friction = 1
#        self.a=complex(0, 0.15)
        
        	self.adr = ["img/pers.png","img/pers_force.png","img/bar.png","img/energie_bar.png"]
        
        	self.position = position
        
        	self.LoadImgs()

        	self.sprite = sf.Sprite(self.img)
        
		self.w = w
		
		self.type = "personnage"


	def StopVertical(self):
		self.v = complex(self.v.real, 0)

        
        def evolution(self,key):
                if key == 1 : #droite
                        self.v = complex(self.vel_moving, self.v.imag)
                elif key == 2 : #gauche
                        self.v = complex(-self.vel_moving, self.v.imag)
                elif key == 3 : #jump
                        if self.jump == False :
                                self.v = complex(self.v.real , -self.vel_jumping)
                                self.jump = True
                elif key == 5  : # fire
                        self.feu = True
                        if self.position == 1 : # gauche
                                self.moteur_p.ajouter_particule(100, 10, 0, self.p.real, self.screen_height-100, 10, "img/fire.png", 80,720,100,0)
                        else : # droite
                                self.moteur_p.ajouter_particule(100, 10, 180, self.p.real, self.screen_height-100, 10, "img/fire2.png", 80,720,100,0)


        def Move(self):
                self.p = complex(self.p.real+self.v.real, self.p.imag)
                self.v = complex(0, self.v.imag)
                boule.Boule.Move(self)

           
        def manage_keys(self, Input):
                if (Input.IsKeyDown(sf.Key.Right)) : # droite
                        self.evolution(1)
                if (Input.IsKeyDown(sf.Key.Left)) : # gauche
                        self.evolution(2)
                if (Input.IsKeyDown(sf.Key.Up)) : # haut
                        self.evolution(3)
                if (Input.IsKeyDown(sf.Key.A)) : # Touche 1 -- deplacement rapide
                        self.evolution(4)
                if (Input.IsKeyDown(sf.Key.S)) : # Touche 2 -- force
                        self.set_force(10)
                if (Input.IsKeyDown(sf.Key.E)) : # Touche 3 -- feu au sol
                        self.evolution(5)



	def LoadImgs(self):
		if not self.img.LoadFromFile(self.adr[0]) :
			print "Error loading file : "+self.adr[0]
		else :
			print self.adr[0]+"   OK"
""" 
		if not self.force_img.LoadFromFile(self.adr[1]) :
			print "Error loading file : "+self.adr[1]
		else :
			print self.adr[1]+"   OK"
		if not self.barre_energie_vide.LoadFromFile(self.adr[2]) :
			print "Error loading file: "+self.adr[2]
		else :
			print self.adr[2]+"   OK"
		if not self.barre_energie.LoadFromFile(self.adr[3]) :
			print "Error loading file :"+self.adr[3]
		else :
			print self.adr[3]+"   OK"
   
   
ETAIT DANS LE CONSRTUCTEUR

       		self.sprite_barre_energie_vide = sf.Sprite(self.barre_energie_vide)
        	self.sprite_barre_energie_vide.SetX(bar_x)
        	self.sprite_barre_energie_vide.SetY(bar_y)
        
        	self.sprite_barre_energie = sf.Sprite(self.barre_energie)
    		self.sprite_barre_energie.SetSubRect(sf.IntRect(0,0,0,2))
	
    		if position == 1 :
    			self.sprite_barre_energie.SetX(bar_x+12)
    		else :
    			self.sprite_barre_energie.SetX(bar_x+170+12)	
    		self.sprite_barre_energie.SetY(bar_y+12)
        
        	self.jump = False
    		self.feu = False
    		self.name = name
    		self.moteur_p = moteur_p

        	self.sprite_pers.SetPosition(self.p.real, self.p.imag)

   
ETAIT DANS LE CONSRTUCTEUR

   
   
   
   
    def Bounce(self,i):
        self.v = complex(self.v.real*-1,self.v.imag)

    def Move(self, w):# pour la compatibilité du gestionnaire de collisisons
        self.affect(w)
        
    def CheckCollision(self, ball):
        # Collision avec un autre objet ball
        if abs(ball.p - self.p) < self.r + ball.r: # uh-oh, collision
            #ball.v = complex(self.v.real-ball.v.real+(ball.p.real-self.p.real)*20, self.v.imag-ball.v.imag+(ball.p.imag-self.p.imag)*20)
            
#            if ball.p.real > self.p.real : # balle à droite du personnage
#                ball.v = (ball.p-self.p)*50
#            else : # balle à gauche
#                ball.v = -(self.p-ball.p)*50
#            ball.Move(self.w)
            # Axe entre le centre des deux balles (normale de la collision)
            n = (ball.p - self.p) / abs(ball.p - self.p)
            vap = (self.v / n).real # On projète la vitesse sur la normale
            van = (-1j * self.v / n).real # On projète la vitesse sur la perpendiculaire à la normale
            # Ensuite on fait pareil pour la vitesse de ball
            vbp = (ball.v / n).real
            vbn = (- 1j * ball.v / n).real

            # Maintenant qu'on a projeté la vitesse dans le repère de la normale et de sa perpendiculaire,
            # le problème est le même que dans le cas d'une seule dimension.
            # On calcule les nouvelles coordonnées de la vitesse après collision dans le nouveau repère,
            # en prenant compte des masses des deux objets.
            s = (self.m+ball.m)
            vap2 = ((self.m-(1-self.bounce_friction)*ball.m)/s)*vap + ((2-self.bounce_friction)*ball.m/s)*vbp
            vbp2 = ((2-ball.bounce_friction)*self.m/s)*vap + ((ball.m-(1-ball.bounce_friction)*self.m)/s)*vbp*2.5
            # Il ne reste plus qu'à revenir dans notre repère bien aimé.
            #self.v = vap2*n + van*n*1j
            ball.v = vbp2*n + vbn*n*1j

            # Pour éviter que les deux balles se rentrent dedans, on corrige la position proportionnellement à
            # la masse relative (le plus léger bouge plus)
            d = self.r + ball.r - abs(ball.p - self.p) + 1
            self.p -= n*d*ball.m/s
            ball.p += n*d*self.m/s
			
			#ball.Move(self.w)

    def getimpact(self):
	       return self.impact
    def setimpact(self, i):
	       self.impact = i

    def getSprite(self):
        return self.sprite_pers
    
    def affect(self, w):

        self.delta = w.GetFrameTime()*100
		
        # Mise à jour de la vitesse
        #self.v = self.v * (1-self.delta*self.friction) + self.a * self.delta
        #self.v = self.v * (1-int(self.delta) * 0.5)
        
        nouvelle_p = self.p + self.v * self.delta
        
        if self.jump == False and self.v.imag == 0.0 :
            if self.v.real > 0 :
                if not self.carte.IsZoneOpaque(self.p.real + self.r*2, nouvelle_p.imag, nouvelle_p.real+self.r*2, nouvelle_p.imag+self.r*2) :
                    self.p += self.v * int(self.delta)
#                    print "Sol"
            else:
                if not self.carte.IsZoneOpaque(nouvelle_p.real, nouvelle_p.imag, self.p.real, nouvelle_p.imag+self.r*2) :
                    self.p += self.v * int(self.delta)
#                    print "Sol"
        elif not self.carte.RoughlyCheckCollision(nouvelle_p.real+self.r, nouvelle_p.imag+self.r, self.r) :
            # Mise à jour de la position
            self.p += self.v * int(self.delta)
#            print "Grossier"
        elif not self.carte.IsZoneOpaque(nouvelle_p.real, nouvelle_p.imag, nouvelle_p.real+self.r*2, nouvelle_p.imag+self.r*2) :
            self.p += self.v * int(self.delta)
#            print "Fin"
        else :
            self.v = complex(self.v.real, 0)
            
#        if self.jump and self.v.imag == 0.0 and self.carte.IsZoneOpaque(nouvelle_p.real+5, nouvelle_p.imag+5, nouvelle_p.real+self.r*2-5, nouvelle_p.imag+self.r*2) :
        if self.jump and self.v.imag == 0.0 :
            self.jump = False
            
        self.sprite_pers.SetPosition(self.p.real, self.p.imag)
        
        if not self.touche_sol():
#        if self.jump == True :
            self.v = complex(self.v.real, self.v.imag + self.vel_grav)
            if self.v.imag == 0:
                self.v = complex(self.v.real, 0.1)
#        elif not self.touche_sol() :
#            self.v = complex(self.v.real, self.v.imag+(self.vel_jumping/((self.screen_height-self.p.imag)/100)))
        else:
            pass
                
    	if self.immobilisation > 0 :
    		self.immobilisation = self.immobilisation - 1
    	else :
#    		if self.getimpact() > 0 :
#    			self.impact = self.impact - 1
#    
#    		self.velx_prec = self.velx
    		self.v = complex(0,self.v.imag)
#    		if self.jump :
#    		    if self.v.imag < 1 :
#    		        self.v += complex(0,self.vel_moving / 6)
#    		    else :
#    		        if ((self.v.imag + self.p.imag)<(self.screen_height - self.sol) and self.v.imag < 30) :
#    		            self.v += complex(0,self.vel_moving/8)
#    		        else :
#    		            self.v = complex(0,(self.screen_height - self.sol)-self.p.imag)
    		
#    		if(self.p.imag >= self.screen_height - self.sol):
#    		    self.jump = False
#    		    self.v = complex(0,0)
    
    		if self.force > 0 :
    			self.sprite_pers.SetImage(self.force_img)
    			self.force = self.force - 1
    		elif self.force == 0 :
    			self.sprite_pers.SetImage(self.img)
    			self.force = -1	
    		
    		self.sprite_pers.SetPosition(self.p.real, self.p.imag)
#    		self.time = self.time + 1
            
    
    		if self.feu == True :
#    			self.time_feu = self.time
    			self.moteur_p.update_particule()
#        print "Fin de l'affect de " + self.getName() + "x/y"
#        print self.p.real
#        print self.p.imag

    def touche_sol(self):
        return self.carte.IsZoneOpaque(self.p.real, self.p.imag+self.r*2, self.p.real+self.r*2, self.p.imag+self.r*2+2)

    def is_feu(self):
	       return self.feu

    def getFeu(self):
	       return self.ofeu

    def getPosFeu(self):
	       return self.ofeu[1].getX()

    def collision_feu(self, x):
	       return (not self.jump and self.p.real > x-self.radius*2 and self.p.real < x)

    def brule(self,t):
	       self.immobilisation = t
    
    def set_force(self,f):
	       self.force = f

    def evolution(self,key):

        if key == 1 : #droite
            self.v = complex(self.vel_moving, self.v.imag)
        elif key == 2 : #gauche
            self.v = complex(-self.vel_moving, self.v.imag)
        elif key == 3 : #jump
                if self.jump == False :
                    self.v = complex(self.v.real , -self.vel_jumping)
                    self.jump = True
        elif key == 5  : # fire
		    self.feu = True
		    if self.position == 1 : # gauche
			          self.moteur_p.ajouter_particule(100, 10, 0, self.p.real, self.screen_height-100, 10, "img/fire.png", 80,720,100,0)
		    else :                  # droite
		              self.moteur_p.ajouter_particule(100, 10, 180, self.p.real, self.screen_height-100, 10, "img/fire2.png", 80,720,100,0)

#	self.keys.append(key)
#	if (self.time - self.time_update) >= 500 :
#		del (self.keys[:])
#	else :
#		if self.test_combo() == 1 :
#			print "rapiddd 1"
#			#self.velx = self.vel_moving * 10
#		elif self.test_combo() == 2 :
#			#print "rapiddd 2"
#			self.v = (-self.vel_moving * 10, self.v.imag)
#		
#		if len(self.keys) > 10:
#			del self.keys[0]
#		self.time_update = self.time

    def test_combo(self): # return : 1 = avance rapide droite, 2 = avance rapide gauche
        droite = 0
        gauche = 0
        A = 0
	
	if self.keys :
		last = self.keys.pop()
		if last == 1 or last == 2 : # droite ou gauche
			for cle in self.keys:
				if cle == 1 : # droite
					droite = droite + 1
				elif cle == 2 : # gauche
					gauche = gauche + 1
		self.keys.append(last)
		
		if droite > 0 and self.jump == True and last == 1 and self.velx_prec == 0 : # droite
			return 1 # avance rapide droite
		elif gauche > 0 and self.jump == True and last == 2 and self.velx_prec == 0 : # gauche
			return 2 # avance rapide gauche
		
    def energie_plus(self):
	self.energie = self.energie+1
	self.sprite_barre_energie.SetSubRect(sf.IntRect(0,0,self.energie,2))
	if self.position == 2 :
		self.sprite_barre_energie.Move(-1,0)

    def getBarFond(self):
	return self.sprite_barre_energie_vide
    def getBar(self):
	return self.sprite_barre_energie
                        
    def collision(self, c1, c2):
	if c1.getimpact() == 0 :
		if((abs(c1.getx()+c1.getRadius()-c2.getx()-c2.getRadius()))<= c1.getRadius()+c2.getRadius()):
		    if((abs(c1.gety()+c1.getRadius()-c2.gety()-c2.getRadius()))<= c1.getRadius()+c2.getRadius()):
			diff_x = c1.getx()+c1.getRadius()-c2.getx()-c2.getRadius()
			dir_x = -1
			if diff_x < 0 :
				diff_x = diff_x * -1
				dir_x = 1
			diff_y = c1.gety()+c1.getRadius()-c2.gety()-c2.getRadius()
			dir_y = -1
			if diff_y < 0 :
				diff_y = diff_y * -1
				dir_y = 1
			
			if self.force > 0 :
				c2.set_vely(diff_y*dir_y/2.0*1.3)
				c2.set_velx(diff_x*dir_x/10.0*1.3)
			else :
				c2.set_vely(diff_y*dir_y/2.0)
				c2.set_velx(diff_x*dir_x/10.0)
			#print "vely =",diff_y*dir_y/1.1
			#print "velx =",diff_x*dir_x/10.0
			c1.setimpact(20)
			self.energie_plus()

#		if(c2.getx()+c2.getRadius()<c1.getx()+c1.getRadius()):
#			if(c2.gety()+c2.getRadius()>c1.gety()+c1.getRadius()):
#				c2.change_vely()
#				c2.change_velx()
#			else :
#				c2.change_velx()
#		else :
#			if(c2.gety()+c2.getRadius()>c1.gety()+c1.getRadius()):
#				c2.change_vely()
#				c2.change_velx()
#			else :
#				c2.change_velx()

    def obstacle(self):
        if self.position == 1 : #gauche
            if self.p.real <= 0 :
                self.p.real = 0
            elif self.p.real + self.radius*2 >= self.screen_width/2 :
                self.p.real = self.screen_width/2 - self.radius*2
            if self.p.imag + self.radius*2 >= self.screen_height - self.sol :
                self.p.imag = self.screen_height - self.radius*2 - self.sol



    def jumping(self):
        return self.jump
    def jumps(self):
        self.jump=true
    def getx(self):
        return self.p.real
    def gety(self):
        return self.p.imag
    def getvelx(self):
        return self.velx
    def getvely(self):
        return self.vely
    def getRadius(self):
        return self.radius
    def setpos(self,x,y):
        self.p = complex(x,y)
    def setXdir(self, xn):
        self.velx=xn
    def setYdir(self, yn):
        self.vely=yn
    def getName(self):
        return self.name
"""

